package com.hylc.biz.ui.update;

import static android.os.Environment.DIRECTORY_DOWNLOADS;
import static com.xls.commonlibrary.util.VersionCodeUtil.computeMD5;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.PowerManager;
import android.text.TextUtils;
import android.util.Log;

import androidx.core.content.FileProvider;

import com.orhanobut.logger.Logger;
import com.xls.commonlibrary.bean.UpdateVersionResult;
import com.xls.commonlibrary.util.SysDataUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class DownloadTask extends AsyncTask<String, Integer, String> {

    // String apkPath = "/sdcard/new.apk";

    //    String apkPath = "/sdcard/";// apk下载的路径目录
    String apkPath = "";// apk下载的路径目录   13兼容

    private Context context;
    UpdateVersionResult result;// 更新的bean
    private ProgressDialog progressDialog;
    private PowerManager.WakeLock mWakeLock;


    public DownloadTask(Context context, UpdateVersionResult result) {
        this.context = context;
        this.result = result;


        //  android 13兼容 读写
        apkPath += this.context.getExternalFilesDir(DIRECTORY_DOWNLOADS) + File.separator;

        // 设置apk的文件名
        if (result != null && !TextUtils.isEmpty(result.getFileName())) {
            this.apkPath += result.getFileName();// root + fileName of server
        } else {
            this.apkPath += "new.apk"; // 备用apk名字
        }

    }

    //onPreExecute(),在execute(Params... params)方法被调用后立即执行，执行在ui线程，
    // 一般用来在执行后台任务前会UI做一些标记
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // take CPU lock to prevent CPU from going off if the user
        // presses the power button during download
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
                getClass().getName());
        mWakeLock.acquire();

        progressDialog = new ProgressDialog(context);
        progressDialog.setMessage("正在下载...");
        progressDialog.setIndeterminate(true);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setCancelable(!"1".equals(result.getForceUpdate()));
        progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
            @Override
            public void onCancel(DialogInterface dialog) {
                cancel(true);
            }
        });


        progressDialog.show();
        Logger.d("=========DownloadTask========= apk file path =========" + apkPath);
    }

    // doInBackground这个方法在onPreExecute()完成后立即执行，
    // 用于执行较为耗时的操作，
    // 此方法接受输入参数
    // 和返回计算结果（返回的计算结果将作为参数在任务完成是传递到onPostExecute(Result result)中），
    // 在执行过程中可以调用publishProgress(Progress... values)来更新进度信息
    //后台任务的代码块
    @Override
    protected String doInBackground(String... url) {
        InputStream input = null;
        OutputStream output = null;
        HttpURLConnection connection = null;
        try {
            URL urll = new URL(url[0]);
            Log.d("upgrade", "url1:" + urll + "////url:" + url);
            connection = (HttpURLConnection) urll.openConnection();
            connection.connect();
            // expect HTTP 200 OK, so we don't mistakenly save error report
            // instead of the file
            if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                return "Server returned HTTP " + connection.getResponseCode()
                        + " " + connection.getResponseMessage();
            }
            // this will be useful to display download percentage
            // might be -1: server did not report the length
            int fileLength = connection.getContentLength();
            // download the file
            input = connection.getInputStream();
//            output = new FileOutputStream("/sdcard/new.apk");
            output = new FileOutputStream(apkPath);
            byte data[] = new byte[4096];
            long total = 0;
            int count;
            while ((count = input.read(data)) != -1) {
                if (isCancelled()) {
                    input.close();
                    return null;
                }
                total += count;
                // publishing the progress....
                if (fileLength > 0) // only if total length is known
                    //在调用这个方法后，执行onProgressUpdate(Progress... values)，
                    //运行在主线程，用来更新pregressbar


                    publishProgress((int) (total * 100 / fileLength));
                output.write(data, 0, count);
            }
        } catch (Exception e) {
            return e.toString();
        } finally {
            try {
                if (output != null)
                    output.close();
                if (input != null)
                    input.close();
            } catch (IOException ignored) {
            }
            if (connection != null)
                connection.disconnect();
        }
        return null;
    }

    //onProgressUpdate(Progress... values),
    // 执行在UI线程，在调用publishProgress(Progress... values)时，此方法被执行。
    @Override
    protected void onProgressUpdate(Integer... progress) {

        // app进入后台依然在运行下载
        // Logger.d("=========DownloadTask=========apk file download=========:"+progress[0]);

        super.onProgressUpdate(progress);
        // if we get here, length is known, now set indeterminate to false
        progressDialog.setIndeterminate(false);
        progressDialog.setMax(100);
        progressDialog.setProgress(progress[0]);
    }

    //onPostExecute(Result result),
    // 执行在UI线程，当后台操作结束时，此方法将会被调用。
    @Override
    protected void onPostExecute(String result) {
        mWakeLock.release();
        progressDialog.dismiss();
        if (result != null) {
            //Toast.makeText(context, "Download error: " + result, Toast.LENGTH_LONG).show();
            Logger.d("=========DownloadTask========= apk file download error =========:" + result);
        } else {
            //Toast.makeText(context, "File downloaded", Toast.LENGTH_SHORT).show();
            Logger.d("=========DownloadTask========= apk file download complete =========");
        }
//这里主要是做下载后自动安装的处理
        // File file = new File("/sdcard/new.apk");
        Logger.d("=========DownloadTask========= apk file check md5 and size =========");
        File file = new File(apkPath);
        String size = this.result.getFileSize();

        Logger.d("======computeMD5=========%s",computeMD5(file));

        if (file != null
                && file.exists()
                && file.length() == Long.parseLong(size)
                && computeMD5(file).toUpperCase()
                .equals(this.result.getFileMd5().toUpperCase())// todo 都需要判空的
        ) {

            Logger.d("=========DownloadTask========= apk file install =========");

            // 校验md5  size
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

            // 机制：app处于后台无法安装apk
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

                String pkgName = SysDataUtil.getInstance().getPkName();
                Uri uri = FileProvider.getUriForFile(context, pkgName + ".android7.fileprovider", file);

                //Uri uri = FileProvider.getUriForFile(context, "com.example.tian  jin.heyilianchuang.chali.calculator20231122.box_heyi_20231122.android7.fileprovider", file);
                intent.setDataAndType(uri, "application/vnd.android.package-archive");
            } else {
                intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
            }
            try {
                context.startActivity(intent);
            } catch (Exception e) {
                Logger.d("=========DownloadTask========= apk file install error=========");
                e.printStackTrace();
            }

        } else {
            Logger.d("=========DownloadTask========= apk file delete =========");
            if (file.exists()) file.delete();
        }


    }

}
